package com.inspur.demo.controller;

import com.inspur.demo.service.HystrixService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.contrib.javanica.conf.HystrixPropertiesManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

/**
 *    
 * 业务控制
 *
 * @desc:
 * @author: li.peng02
 * @date: 2019/3/22
 * @version: v1.0 
 */
@RestController
public class HystrixController {

    @Autowired
    private HystrixService hystrixService;

    /**
     * @HystrixCommand 由名为javanica的Netflix contrib库提供 。
     * Spring Cloud在连接到Hystrix断路器的代理中使用该注解自动包装Spring bean。
     * 断路器计算何时打开和关闭电路，以及在发生故障时应该做什么。
     */

    /**
     * @param id
     * @return
     */
    @GetMapping("/get1/{id}")
    @HystrixCommand(fallbackMethod = "getError")
    public String get1(@PathVariable String id) {
        try {
            System.out.println(Thread.currentThread().getName() + ":get1 before sleep 5s....");
            Thread.sleep(1000 * 5);
            System.out.println(Thread.currentThread().getName() + ":get1 after sleep 5s....");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "get1." + id;
    }

    /**
     * 测试SEMAPHORE和THREAD隔离策略
     * <p>
     * execution.isolation.strategy 默认为THREAD
     *
     * @param id
     * @return
     * @return: String
     */
    @GetMapping("/get2/{id}")
    @HystrixCommand(fallbackMethod = "getError", commandProperties = {
            // @HystrixProperty(name=HystrixPropertiesManager.EXECUTION_ISOLATION_STRATEGY, value="THREAD")
            @HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_STRATEGY, value = "SEMAPHORE")
    })
    public String get2(@PathVariable String id) {
        try {
            System.out.println(Thread.currentThread().getName() + ":get2 before sleep 5s....");
            Thread.sleep(1000 * 5);
            System.out.println(Thread.currentThread().getName() + ":get2 after sleep 5s....");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "get2." + id;
    }

    /**
     * execution.isolation.thread.interruptOnTimeout 参数,默认为true
     *
     * @param id
     * @return
     * @return: String
     */
    @GetMapping("/get3/{id}")
    @HystrixCommand(fallbackMethod = "getError", commandProperties = {
            //设置超时的时候不中断线程,默认为true
            @HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_THREAD_INTERRUPT_ON_TIMEOUT, value = "false")
    })
    public String get3(@PathVariable String id) {
        try {
            System.out.println(Thread.currentThread().getName() + ":get3 before sleep 5s....");
            Thread.sleep(1000 * 5);
            System.out.println(Thread.currentThread().getName() + ":get3 after sleep 5s....");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "get3." + id;
    }

    /**
     * fallback.isolation.semaphore.maxConcurrentRequests默认为10
     *
     * @param id
     * @return
     * @return: String
     */
    @GetMapping("/get4/{id}")
    @HystrixCommand(fallbackMethod = "getError", commandProperties = {
            @HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_STRATEGY, value = "SEMAPHORE"),
            @HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_SEMAPHORE_MAX_CONCURRENT_REQUESTS, value = "1")
    })
    public String get4(@PathVariable String id) {
        try {
            System.out.println(Thread.currentThread().getName() + ":get4 before sleep 5s....");
            Thread.sleep(1000 * 5);
            System.out.println(Thread.currentThread().getName() + ":get4 after sleep 5s....");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "get4." + id;
    }


    /**
     * execution.timeout.enabled 默认为true, 是否超时
     *
     * @param id
     * @return
     * @return: String
     */
    @GetMapping("/get5/{id}")
    @HystrixCommand(fallbackMethod = "getError", commandProperties = {
            @HystrixProperty(name = HystrixPropertiesManager.EXECUTION_TIMEOUT_ENABLED, value = "false")
    })
    public String get5(@PathVariable String id) {
        try {
            System.out.println(Thread.currentThread().getName() + ":get5 before sleep 5s....");
            Thread.sleep(1000 * 5);
            System.out.println(Thread.currentThread().getName() + ":get5 after sleep 5s....");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "get5." + id;
    }

    /**
     * execution.isolation.thread.timeoutInMilliseconds 默认为1000
     *
     * @param id
     * @return
     * @return: String
     */
    @GetMapping("/get6/{id}")
    @HystrixCommand(fallbackMethod = "getError", commandProperties = {
            @HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_THREAD_TIMEOUT_IN_MILLISECONDS, value = "6000")
    })
    public String get6(@PathVariable String id) {
        try {
            System.out.println(Thread.currentThread().getName() + ":get6 before sleep 5s....");
            Thread.sleep(1000 * 5);
            System.out.println(Thread.currentThread().getName() + ":get6 after sleep 5s....");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "get6." + id;
    }

    public String getError(String id) {
        System.out.println(Thread.currentThread().getName() + ":getError before ....");
        hystrixService.execute();
        System.out.println(Thread.currentThread().getName() + ":getError after ....");
        return "超时错误,使用断路器返回" + id;
    }
}
